home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1995 October / EnigmA AMIGA RUN 01 (1995)(G.R. Edizioni)(IT)[!][issue 1995-10][Aminet 7].iso / Aminet / util / misc / cookies.lha / Cookie / cookie.c < prev    next >
C/C++ Source or Header  |  1995-04-27  |  4KB  |  156 lines

  1. /* cookie - print out an entry from the sayings file
  2.  * by Karl Lehenbauer (karl@sugar.uu.net, uunet!sugar!karl)
  3.  *  cookie.c  1.1  1/12/89
  4.  */
  5.  
  6. /*
  7.  * 1995-04-19 [JöG] changed the random number generation a bit
  8.  *                  didn't bump revision though
  9.  *
  10.  * 1995-04-27 [JöG] different cookie file format now; there are
  11.  *                  as many cookies now as there are entries in
  12.  *                  the hash file
  13.  *                  version bumped to cookie 2.0 due to the changed
  14.  *                  format and the lexified 'cookhash'
  15.  *
  16.  */
  17.  
  18. #include <math.h>
  19. #include <stdio.h>
  20. #include <stdlib.h>
  21. #include <time.h>
  22.  
  23. #include <proto/exec.h>
  24.  
  25. #include "cookie.h"
  26.  
  27. #define ENTSIZE 7L
  28. #define METACHAR '%'
  29. #define YES 1
  30. #define NO 0
  31.  
  32. /*
  33.  * char *sccs_id = "@(#) fortune cookie program 1.1 1/12/89 by K. Lehenbauer";
  34.  */
  35.  
  36. static char verstring[] = "$" "VER: cookie 2.0 (27.4.95)";
  37.  
  38. char *cookiename = COOKIEFILE;
  39. char *hashname = HASHFILE;
  40.  
  41. /* really_random - insure a good random return for a range, unlike an arbitrary
  42.  * random() % n, thanks to Ken Arnold, Unix Review, October 1987
  43.  * ...likely needs a little hacking to run under Berkely
  44.  */
  45. #define RANDOM_RANGE ((1 << 15) - 1)
  46. int really_random(int my_range)
  47. {
  48.     int max_multiple, rnum;
  49.  
  50.     max_multiple = RANDOM_RANGE / my_range;
  51.     max_multiple *= my_range;
  52.     while ((rnum = rand()) >= max_multiple)
  53.         continue;
  54.     return(rnum % my_range);
  55. }
  56.  
  57. main(int argc,char *argv[])
  58. {
  59.     int nentries, oneiwant, c, sawmeta = 0;
  60.     FILE *hashf, *cookief;
  61.     long cookiepos;
  62.  
  63.     /* if we got exactly three arguments, use the cookie and hash
  64.      * files specified
  65.      */
  66.     if (argc == 3)
  67.     {
  68.         cookiename = argv[1];
  69.         hashname = argv[2];
  70.     }
  71.     /* otherwise if argc isn't one (no arguments, specifying the
  72.      * default cookie file), barf
  73.      */
  74.     else if (argc != 1)
  75.     {
  76.         fputs("usage: cookie cookiefile hashfile\n",stderr);
  77.         exit(1);
  78.     }
  79.  
  80.     /* open the cookie file for read */
  81.     if ((cookief = fopen(cookiename,"r")) == NULL)
  82.     {
  83.         perror(cookiename);
  84.         exit(2);
  85.     }
  86.  
  87.     /* open the hash file for read */
  88.     if ((hashf = fopen(hashname,"r")) == NULL)
  89.     {
  90.         perror(hashname);
  91.         exit(2);
  92.     }
  93.  
  94.     /* compute number of cookie addresses in the hash file by
  95.      * dividing the file length by the size of a cookie address
  96.      * and subtract 1 (after the last %% is no cookie)
  97.      * Yes there is! [JöG]
  98.      *
  99.      */
  100.     if (fseek(hashf,0L,2) != 0)
  101.     {
  102.         perror(hashname);
  103.         exit(3);
  104.     }
  105.     nentries = (ftell(hashf) / ENTSIZE) - 1 + 1;
  106.  
  107.     /* seed the random number generator with time in seconds plus
  108.      * the program's process ID - it yields a pretty good seed
  109.      * again, thanks to Ken Arnold
  110.      * AMK: FindTask()
  111.      */
  112.     srand((long)FindTask(NULL) + time(NULL));
  113.  
  114.     /*
  115.      * AMK: get a dummy value
  116.      */
  117.     rand();
  118.  
  119. #if 1
  120.     /* generate a not really random number */
  121.     /* this was the original unix s5r4 version, too sophisticated */
  122.        oneiwant = really_random(nentries);
  123. #else
  124.     /* this is version seems to be random enough ;-) (AMK) */
  125.     oneiwant = rand() % nentries;
  126. #endif
  127.  
  128.     /* locate the one I want in the hash file and read the
  129.      * address found there
  130.      */
  131.     fseek(hashf,(long)oneiwant * ENTSIZE, 0);
  132.     fscanf(hashf,"%lx",&cookiepos);
  133.  
  134.     /* seek cookie file to cookie starting at address read from hash */
  135.     fseek(cookief,cookiepos,0);
  136.  
  137.     /* get characters from the cookie file and write them out
  138.      * until finding the end-of-fortune sequence, '%%'
  139.      */
  140.     while ((c = fgetc(cookief)) != EOF && sawmeta < 2)
  141.     {
  142.         if (c != METACHAR)
  143.         {
  144.             if (sawmeta)
  145.                 putchar(METACHAR);
  146.             putchar(c);
  147.             sawmeta = 0;
  148.         }
  149.         else
  150.             sawmeta++;
  151.     }
  152.     exit(0);
  153. }
  154.  
  155. /* end of cookie.c */
  156.